package framework.common;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionLikeType;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * json操作帮助类
 * 默认都依赖jackson实现方法，若用到其他框架，框架名称需要在方法钟体现出来
 *
 * @author guochuang
 * @version 6.2
 * @date 2022/02/17 14:45
 */
@Slf4j
public class
JsonHelper {


    private static final class ObjectMapperHolder {
        static final ObjectMapper objectMapper = new ObjectMapper();

    }

    static {
        // 忽略bean中不存在的属性
        ObjectMapperHolder.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static String toJsonString(Object object) {

        try {
            return ObjectMapperHolder.objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            log.error("对象转json字符串错误 err {}", e.getMessage());
            e.printStackTrace();
            return "";
        }
    }

    /**
     *
     * 转fastjson的JSONObject
     *
     * @param object    obj
     * @return          JSONObject
     */
    public static JSONObject toJsonObject(Object object) {
        return JSONObject.parseObject(JSONObject.toJSON(object).toString());
    }

    /**
     *
     * 转fastjson的JSONObject集合
     *
     * @param object        obj
     * @return              集合
     */
    public static List<JSONObject> toFastJsonObjects(Object object) {

        List<JSONObject> list = new ArrayList<>();
        JSONArray jsonArray = JSONArray.parseArray(object.toString());
        for (Object obj : jsonArray) {
            JSONObject jsonObject = toJsonObject(obj);
            list.add(jsonObject);
        }
        return list;
    }

    /**
     *
     * java对象转json字符串
     *
     * @param javaObject    java对象
     * @return              json字符串
     */
    public static String javaObjectToJsonObject(Object javaObject){

        try {
            if (javaObject!=null) {
                return ObjectMapperHolder.objectMapper.writeValueAsString(javaObject);
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     *
     * json字符串转java对象
     *
     * @param jsonString        json字符串
     * @param targetClazz       期望类型
     * @param <T>               泛型
     * @return                  java对象
     */
    public static <T> T jsonObjectToJavaObject(String jsonString, Class<T> targetClazz){

        T t = null;
        try {
            t = ObjectMapperHolder.objectMapper.readValue(jsonString,targetClazz);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return t;
    }

    /**
     *
     * json字符串转java对象
     *
     * @param object            数据
     * @param targetClazz       期望类型
     * @param <T>               泛型
     * @return                  java对象
     */
    public static <T> T jsonObjectToJavaObject(Object object, Class<T> targetClazz){

        T t = null;
        try {

            t = ObjectMapperHolder.objectMapper.readValue(javaObjectToJsonObject(object),targetClazz);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return t;
    }

    /**
     *
     * json数组字符串转java集合
     *
     * @param jsonArrayString           json字符串
     * @param targetClazz               期望的类型
     * @param <T>                       泛型
     * @return                          java集合
     */
    public static <T> List<T> jsonArrayStringToJavaList(String jsonArrayString, Class<T> targetClazz){

        CollectionLikeType collectionLikeType = ObjectMapperHolder.objectMapper.getTypeFactory().constructCollectionType(List.class, targetClazz);
        try {
            return ObjectMapperHolder.objectMapper.readValue(jsonArrayString, collectionLikeType);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}
